home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 4_0 / STANDALO / TOGSNDVO / TSV_SOUR / TOGSNDVO.C < prev   
C/C++ Source or Header  |  1991-02-11  |  9KB  |  325 lines

  1. /* ToggleSndVol FKEY 3.1
  2.    ⌐1990, 1991, by Mike Gleason Jr. (NCEMRSoft) 
  3.    Think C 4.x Source code and object code both
  4.    may be distributed freely. 
  5.    
  6.    Think C 4.x setup:
  7.    Make a project and add MacTraps.  Set Project Type to "Code Resource,"
  8.    and set the TYPE to "FKEY" and the ID number to 7 (or whatever╔).
  9.    I also suggest setting the "Attrs" to "purgeable" only, the NAME to
  10.    ToggleSndVol 3.1, and the File's type/creator to FKEY/MKEY.  */
  11.    
  12.  
  13.  
  14. #define CANCEL_BUTTON_ID         8    /* id number of "Cancel" */
  15. #define ABOUT_BUTTON_ID            9    /* id number of "?" */
  16. #define NULL                    0L    /* duh */
  17. #define SMALLBUTTONSIZE            15    /* how wide and tall a button is */
  18. #define BUTTONMARGIN            3    /* number of pixels between buttons */
  19. #define WINDOWWIDTH                222    /* dimensions of the window in pixels */
  20. #define WINDOWHEIGHT            23
  21.  
  22. #define FKEY                     /* Comment that if you are testing. */
  23.  
  24. /* function prototypes... */
  25. #pragma mark _prototypes
  26. short    DoIt(void);                    /* the main event loop */
  27. void    GetScreenBitsBounds(Rect *ScreenBitsBounds);
  28.                                     /* Get Screen dimensions */
  29. short    ModifierDown(void);            /* is the option, shift, or cmd down? */
  30. void    SaveToPRAM(short newvol);    /* write newvol to the control panel PRAM */
  31. void    SetTheVolume(short theVol);    /* sets the speaker's volume */
  32. void    DoAbout(WindowPtr w, char *text);
  33.                                     /* extend the window, show info */
  34.  
  35. #ifdef FKEY
  36. #include <SetUpA4.h>
  37. #endif
  38.  
  39. main() 
  40. {    
  41. #ifdef FKEY
  42.     Handle            h;
  43.      
  44.     RememberA0();
  45.     SetUpA4();
  46.     
  47.     asm
  48.     {                            ;guarantee that INIT is locked even
  49.         _RecoverHandle            ;if locked bit was not set with ResEdit
  50.         move.l    a0,h            ;save away handle to unlock later
  51.         _HLock                    ;handle is already in a0
  52.     }
  53.     InitCursor();
  54. #else    /* we're testing with an application. */
  55.     MaxApplZone();
  56.     
  57.     InitGraf(&thePort);
  58.     InitFonts();
  59.     FlushEvents(everyEvent, 0);
  60.     InitWindows();
  61.     InitMenus();
  62.     TEInit();
  63.     InitDialogs(0L);
  64.     InitCursor();
  65. #endif
  66.  
  67.     if (!DoIt())
  68.     {
  69.         SysBeep(3L); SysBeep(3L);    /* we got an error. */
  70.     }
  71.     
  72. #ifdef FKEY
  73.     HUnlock(h);
  74.     /* DisposHandle(h); better let the system do that! */
  75.     RestoreA4();
  76. #endif
  77.     return;
  78. }    /* main */
  79.     
  80.  
  81.  
  82.  
  83. short    DoIt(void)
  84. {
  85.     Rect             theRect;
  86.     WindowPtr        theWind;
  87.     short            sndVol;
  88.     short            done = 0;
  89.     long            dummy;
  90.     Rect            itemRect, ScreenBitsBounds;
  91.     ControlHandle    buttons[9], whichControl;
  92.     register short    i;
  93.     Str255            title;
  94.     EventRecord        theEvent;
  95.     char             ch;
  96.      char text[] =     "ToggleSndVol FKEY 3.1\r⌐1991 by Mike Gleason, NCEMRSoft.\r\rClicking or typing a number sets the sound volume in the Control Panel to that number.  Hold"
  97.                     "ing down the option key will NOT save the result to the PRAM (the change will only last for this boot).  This FKEY is FREE :-) ";
  98.  
  99.     /*    This block of statements creates and "centers" (according to
  100.         Apple's liking) the little window's rectangle. */
  101.     theRect.top = theRect.left = 0;
  102.     theRect.right = WINDOWWIDTH;
  103.     theRect.bottom = WINDOWHEIGHT;
  104.     /* but first we need to get the screen dimensions. */
  105.     GetScreenBitsBounds(&ScreenBitsBounds);
  106.     OffsetRect(&theRect,(ScreenBitsBounds.right-theRect.right)/2,(ScreenBitsBounds.bottom-theRect.bottom)/3);
  107.  
  108.     /*    OK, we've got the rectangle, now make the window. */
  109.     theWind = NewWindow((Ptr) 0, &theRect, "\pdumb╔", false, dBoxProc, (WindowPtr) -1, false, 0);
  110.     if (!theWind) return (0);
  111.  
  112.     /*    Get ready to draw in our window */
  113.     SetPort(theWind);
  114.     ShowWindow(theWind);
  115.     SelectWindow(theWind);
  116.     
  117.     /*    Create the first button's rectangle. */
  118.     theRect.left = theRect.top = 2;
  119.     theRect.bottom = theRect.right = theRect.top + SMALLBUTTONSIZE;
  120.     
  121.     /* This loop creates 8 little buttons, numbered 0-7. */
  122.     for (i=0; i<8; i++)
  123.     {
  124.         NumToString((long) i, title);    /* convert 3 shorto "3", etc. */
  125.         buttons[i] = NewControl(
  126.             theWind,
  127.             &theRect,
  128.             title,
  129.             true,
  130.             0,
  131.             0,
  132.             0,
  133.             pushButProc,
  134.             i
  135.         );
  136.         if (!buttons[i]) return (0);
  137.         /* Shift the rectangle to use for the next button. */
  138.         theRect.right += SMALLBUTTONSIZE + BUTTONMARGIN;
  139.         theRect.left += SMALLBUTTONSIZE + BUTTONMARGIN;
  140.     }
  141.     
  142.     /*    We've already got the rectangle, but it's too narrow. 
  143.         Add on enough pixels to fit in the word "Cancel." */
  144.     theRect.right += StringWidth("\pCancel");
  145.     buttons[CANCEL_BUTTON_ID] = NewControl(theWind, &theRect, "\pCancel", 1,0,0,0,0,CANCEL_BUTTON_ID);
  146.     if (!buttons[CANCEL_BUTTON_ID]) return (0);
  147.     
  148.     /*    Grr... Now we need the old dimensions back for a small button. */
  149.     theRect.right += SMALLBUTTONSIZE + BUTTONMARGIN;
  150.     theRect.left = theRect.right - SMALLBUTTONSIZE;
  151.     buttons[ABOUT_BUTTON_ID] = NewControl(theWind, &theRect, "\p?", 1,0,0,0,0,ABOUT_BUTTON_ID);
  152.     if (!buttons[ABOUT_BUTTON_ID]) return (0);
  153.     
  154.     /*     This block gets the current sound volume, so we can put a dot under
  155.         the appropriate button in the window to tell the user what the
  156.         current speaker volume is. */
  157.     GetSoundVol(&sndVol);
  158.     theRect.left = ((**buttons[sndVol]).contrlRect.right-(**buttons[sndVol]).contrlRect.left)/2 - 2 + (**buttons[sndVol]).contrlRect.left;
  159.     theRect.top = (**buttons[sndVol]).contrlRect.bottom+2;
  160.     theRect.right = theRect.left + 4;
  161.     theRect.bottom = theRect.top + 4;
  162.     PaintOval(&theRect);
  163.     
  164.     /*    Now everything should be up and running.  What follows is a really
  165.         short and ugly event loop;  We only care about mouseDown and
  166.         keyDown events. */
  167.  
  168.     while (!done)
  169.     {
  170.         if (GetNextEvent(everyEvent, &theEvent))
  171.         {
  172.             if (theEvent.what == mouseDown)
  173.             {
  174.                 if (FindWindow (theEvent.where, &theWind) == inContent);
  175.                 {
  176.                     /* if a button was clicked... */
  177.                     SetPort(theWind);
  178.                     GlobalToLocal(&theEvent.where);
  179.                     if (FindControl(theEvent.where, theWind, &whichControl))
  180.                     {
  181.                         /* see which button it was, and hilite it as needed. */
  182.                         if (TrackControl(whichControl, theEvent.where, 0L))
  183.                         {
  184.                             ch = (**whichControl).contrlRfCon;
  185.                             done = 1;
  186.                             if (ch < CANCEL_BUTTON_ID && ch >= 0)
  187.                                 SetTheVolume((short) ch);
  188.                             else if (ch == ABOUT_BUTTON_ID)
  189.                             {
  190.                                 DoAbout(theWind, text);
  191.                                 done = 0;
  192.                             }
  193.                             /* else you hit cancel */
  194.                             /* so do nothing but exit */
  195.                         }
  196.                     }
  197.                     
  198.                 }                
  199.             }
  200.             else if (theEvent.what == keyDown || theEvent.what == autoKey)
  201.             {
  202.                 ch = (char) (theEvent.message & charCodeMask);
  203.                 if (ch >= '0' && ch <= '7')
  204.                     ch -= '0';    /* convert ch to a real number */
  205.                 else if (ch == '/' || ch == '?')
  206.                     ch = ABOUT_BUTTON_ID;    /* about */
  207.                 else
  208.                     ch = CANCEL_BUTTON_ID;    /* cancel */
  209.                 HiliteControl(buttons[ch], 1);    /* psuedoclick the button */
  210.                 Delay(20, &dummy);
  211.                 HiliteControl(buttons[ch], 0);
  212.                 done = 1;
  213.                 if (ch < CANCEL_BUTTON_ID)
  214.                     SetTheVolume((short) ch);
  215.                 else if (ch == ABOUT_BUTTON_ID)
  216.                 {
  217.                     DoAbout(theWind, text);
  218.                     done = 0;
  219.                 }
  220.             }
  221.         }
  222.     }
  223.     EraseRect(&theWind->portRect);
  224.     DisposeWindow(theWind);
  225.     
  226.     return (1);    /* successful */
  227.     
  228. }    /* DoIt() */
  229.  
  230.  
  231.  
  232.  
  233. void    GetScreenBitsBounds(Rect *ScreenBitsBounds)
  234. {
  235.     GrafPort    tempPort;
  236.     GrafPtr        savedPort;
  237.     
  238.     GetPort(&savedPort);        /* finding screenBits w/o globals */
  239.     OpenPort(&tempPort);
  240.     *ScreenBitsBounds = tempPort.portRect;
  241.     SetPort(savedPort); 
  242.     ClosePort(&tempPort);
  243. }    /* GetScreenBitsBounds */
  244.  
  245.  
  246.  
  247.  
  248. void    SetTheVolume(short theVol)
  249. {
  250.     /*    If the option key is not down, we'll assume the change is
  251.         permanent; if it is down, we won't store the change in the PRAM. */
  252.     if (!ModifierDown())
  253.         SaveToPRAM(theVol);
  254.     SetSoundVol(theVol);
  255.     SysBeep(3L);    /*    Beep so the user can hear the new volume. */
  256. }    /* SetTheVolume */
  257.  
  258.  
  259.  
  260. short        ModifierDown(void)
  261. {
  262.     KeyMap k;
  263.     
  264.     GetKeys(&k);
  265.     if (BitTst(&k, 61) ||  BitTst(&k, 48) ||  BitTst(&k, 63))
  266.         return (1);    /* if option, shift, or command is down */
  267.     else
  268.         return (0);
  269. }    /* ModifierDown */
  270.  
  271.  
  272.  
  273.  
  274. void    SaveToPRAM(short newvol)
  275. {
  276.     SysPPtr        sp;
  277.     OSErr        err;
  278.     register     short i;
  279.     
  280.     sp = GetSysPPtr();            /* a poshorter to the PRAM */
  281.     newvol = newvol << 8;        
  282.  
  283.     /*     this block compares 3 bits in our volume to 3 in that of the
  284.         sp->volClik field.  we can't just say sp->volClik = newvol
  285.         because other "useful" data are stored in the other 13 bits
  286.         of the field.  essentially, this block replaces the old 3 bits
  287.         with our 3 bits. */
  288.     for (i=0; i<3; i++)
  289.     {
  290.         if (BitTst(&newvol, i+5))
  291.             BitSet(&sp->volClik, i+5);
  292.         else
  293.             BitClr(&sp->volClik, i+5);
  294.     }
  295.     err = WriteParam();    /* now save the changed sp to the PRAM */
  296. }
  297.  
  298.  
  299.  
  300.  
  301.  
  302.  
  303. void    DoAbout(WindowPtr w, char *text)
  304. {
  305.     Rect r;
  306.  
  307.     /*     All DoAbout() does is stretch the window down when the "?" button
  308.         is clicked so I can put up my about info. */
  309.         
  310.     if (w->portRect.bottom > WINDOWHEIGHT) return;
  311.         /* (The window has already been stretched and is showing the info) */
  312.     
  313.     SetPort(w);
  314.     TextFont(geneva);
  315.     TextSize(9);
  316.     SizeWindow(w, w->portRect.right, w->portRect.bottom + 100, TRUE);
  317.     r = w->portRect;
  318.     r.top = WINDOWHEIGHT+3;
  319.     TextBox(text, (long) 276, &r, teJustLeft);
  320. }
  321.  
  322.  
  323.  
  324.  
  325.